package com.arrake.utils;

import com.arrake.pojo.Docx;
import com.arrake.pojo.DocxParagraph;
import com.arrake.pojo.DocxPicture;
import com.arrake.pojo.DocxText;
import org.dom4j.*;


import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class FormatToReplace {
    //        处理着重号 XML!
    public static void markEmphasis(Document document) {
        List list = document.selectNodes("//w:rPr/w:em[@w:val=\"dot\"]");
        for (Object o : list) {
            Node node = (Node) o;
            Element rPr = node.getParent();
            Element parent = rPr.getParent();
            parent.remove(rPr);
            List list1 = parent.selectNodes("./w:t");
            for (Object o1 : list1) {
                Node node1 = (Node) o1;
                node1.setText("&lt;u&gt;" + node1.getText() + "&lt;/u&gt;");
            }
        }
    }

    //        处理文本居中 XML!
    public static void textCenter(Document document) {
        List list = document.selectNodes("//w:pPr/w:jc[@w:val=\"center\"]");
        for (Object o : list) {
            Node node = (Node) o;
            Element pPr = node.getParent();
            Element p = pPr.getParent();
            p.remove(pPr);
            String pText = "";
            List list1 = p.selectNodes("./w:r/w:t");
            for (int i = 0; i < list1.size(); i++) {
                Object o1 = list1.get(i);
                Node node1 = (Node) o1;
                pText = pText + node1.getText();
                node1.setText("");
                if (i == (list1.size()-1) ){
                    node1.setText("&lt;center&gt;" + pText + "&lt;/center&gt;");
                }
            }
//            for (Object o1 : list1) {
//                Node node1 = (Node) o1;
//                node1.setText("&lt;center&gt;" + node1.getText() + "&lt;/center&gt;");
//            }
        }
    }

    //         对材料添加段落标签 Text！
    public static String paragraphTags(String material) {
        String[] split = material.split("\n");
        material = "";
        for (String s : split) {
            if (s.contains("&lt;/p&gt;")) {
                material = material + s+"\n";
            } else {
                material = material + "&lt;p&gt;" + s + "&lt;/p&gt;\n";
            }
        }

        return material;
    }

    //Text to docx
    public static void textToDocx(String text, Document resXml, String filePath) throws Exception {
//        Matcher matcher = Pattern.compile("（.*").matcher(text);
// //        while (matcher.find()) {
// //            text = text.replace(matcher.group(), matcher.group() + "）");
// //        }
// //        while (text.contains("\n\n")) {
// //            text = text.replaceAll("\n\n", "\n");
//        }
        String[] split = text.split("\n");
        Map<String, String> mapId = getMapPath(resXml);
        Docx docx = new Docx();
        for (String p : split) {
            Matcher matcher1 = Pattern.compile("&lt;img.*?/&gt;").matcher(p);
            if (matcher1.find()) {
                //如果含有图片的处理逻辑
                matcher1.reset();
                DocxParagraph docxParagraph = new DocxParagraph();
                while (matcher1.find()) {
                    Matcher matcher = Pattern.compile("(.*?)(&lt;img.*?/&gt;)(.*)").matcher(p);
                    String picture = null;
                    String text1 = null;
                    while (matcher.find()) {
                        text1 = matcher.group(1);
                        picture = matcher.group(2);
                        p = matcher.group(3);

                    }
                    //文本处理
                    DocxText docxText = new DocxText();
                    docxText.setText(text1);
                    docxParagraph.addText(docxText);
                    //图片处理
                    //获取id与style
                    Matcher matcher2 = Pattern.compile("style=\"(.*?)\"").matcher(picture);
                    String style = null;
                    String id = null;
                    while (matcher2.find()) {
                        style = matcher2.group(1);
                    }
                    Matcher matcher3 = Pattern.compile("id=\"(.*?)\"").matcher(picture);
                    while (matcher3.find()) {
                        id = matcher3.group(1);
                    }

                    DocxPicture docxPicture = new DocxPicture(mapId.get(id), style, id, filePath);
                    docxParagraph.addPicture(docxPicture);
                }
                DocxText docxText = new DocxText();
                docxText.setText(p);
                docxParagraph.addText(docxText);
                docx.addParagraph(docxParagraph);

            } else {
                DocxText docxText = new DocxText();
                docxText.setText(p);
                DocxParagraph docxParagraph = new DocxParagraph();
                docxParagraph.addText(docxText);
                docx.addParagraph(docxParagraph);
            }

        }

        Matcher matcher = Pattern.compile(".+\\\\(.+)\\.").matcher(filePath);
        if (matcher.find()) {
            docx.createDocx(filePath);
        } else {
            throw new Exception("无法获取该文件名");
        }

    }


    //Xml to Text
    public static String xmlToText(Document document) {
        String docText = "";
        List list04 = document.selectNodes("//w:p");
        for (Object o1 : list04) {
            String p = "";
            Element pNode = (Element) o1;
//            List elements = pNode.elements();
//            for (Object element : elements) {
//                Element r = (Element) element;
//                List elements1 = r.elements();
//                for (Object el : elements1) {
//                    Element t = (Element) el;

//                    p = p + t.getText();
//                }
//            }
            List list = pNode.selectNodes("./w:r/w:t");
            for (Object o2 : list) {
                Node tNode = (Node) o2;
                p = p + tNode.getText();
            }
            docText = docText + p + "\n";
        }
        return docText;
    }

    //Picture to Label
    //将图片换成<img style="?" id="?"/>
    public static void picToLabel(Document docXml) {
        List list = docXml.selectNodes("//w:object/v:shape/v:imagedata");

        for (Object o : list) {
            //获取属性
            Element node = (Element) o;
            String id = node.attributeValue("id");
            String style = node.getParent().attributeValue("style");

            //替换标签
            Element delNode = node.getParent().getParent();
            Element parent = delNode.getParent();
            parent.remove(delNode);

            Element element = parent.addElement("w:t");
            element.setText("&lt;img style=\"" + style + "\" id=\"" + id + "\"/&gt;");
        }


    }

    //转换tab为\t
    public static void tabTo(Document document) {
        List list03 = document.selectNodes("//w:r/w:tab");
        for (Object o : list03) {
            Node node = (Node) o;
            Element parent = node.getParent();
            parent.remove(node);
            Element element = parent.addElement("w:t");
            element.setText("\t");
        }
    }

    //替换数字序列号
    public static void serialNumberTo(Document document, String filePath) throws Exception {
        List list = document.selectNodes("//w:pPr/w:numPr");
        if (list == null) {
            return;
        }
        Document numbering = DocxReader.readerNumbering(filePath);
        if (numbering == null) {
            return;
        }
        Map<String, String> mapStart = getMapNumStart(numbering);
        String temp = null;
        int num = 0;
        for (Object o : list) {
            Element numPr = (Element) o;
            String val = null;

            List numIdList = numPr.selectNodes("./w:numId");
            for (Object o1 : numIdList) {
                Element numId = (Element) o1;
                val = numId.attributeValue("val");


//                将节点添加到最前
//                Element r = numId.getParent().getParent().addElement("w:r");
//                Element t = r.addElement("w:t");
//                Element r = DocumentHelper.createElement("w:r").addNamespace("w"," http://schemas.openxmlformats.org/wordprocessingml/2006/main");
                Element r = DocumentHelper.createElement(QName.get("r", numId.getParent().getParent().getNamespace ()));
                Element t = r.addElement("w:t");
//                Element t = DocumentHelper.createElement(QName.get("w:t", numId.getParent().getParent().getNamespace ()));

                String id = mapStart.get(val);
                if (id == null) {
                    continue;
                }
                if (temp == null) {
                    t.setText(id+".");
                    temp = val;
                } else if (temp.equals(val)) {
                    num++;
//                System.out.println(val);
//                System.out.println(mapStart.get(val));
                    t.setText((Integer.parseInt(id) + num) + ".");
                    temp = val;
                } else if (!temp.equals(val)) {
                    num = 0;
                    t.setText(id + ".");
                    temp = val;
                }
                Element parent = numPr.getParent().getParent();
                List elements = parent.elements();
//                for (Object element : elements) {
//                    Element test = (Element) element;
//                    System.out.println(test.asXML());
//                }
//                System.out.println("--------------");
                elements.add(1, r);
//                for (Object element : elements) {
//                    Element test = (Element) element;
//                    System.out.println(test.asXML());
//
//                }
//                System.out.println("-----------");
            }
        }
//        System.out.println(document.asXML());
    }
//    大写字母序列号
    public static void upperTO(Document document, String filePath) throws Exception {
        List list = document.selectNodes("//w:pPr/w:numPr");
        if (list == null) {
            return;
        }
        Document numbering = DocxReader.readerNumbering(filePath);
        if (numbering == null) {
            return;
        }
        Map<String, String> mapStart = getMapUpperStart(numbering);
        String temp = null;
        int num = 0;
        for (Object o : list) {
            Element numPr = (Element) o;
            String val = null;

            List numIdList = numPr.selectNodes("./w:numId");
            for (Object o1 : numIdList) {
                Element numId = (Element) o1;
                val = numId.attributeValue("val");


                Element r = DocumentHelper.createElement(QName.get("r", numId.getParent().getParent().getNamespace ()));
                Element t = r.addElement("w:t");

                String id = mapStart.get(val);
                if (id == null) {
                    continue;
                }
                if (temp == null) {
                    t.setText("A"+".");
                    temp = val;
                } else if (temp.equals(val)) {
                    num++;
                    //这里感觉杀鸡用牛刀了，不知道有没有更好的方式，反正我是没有百度到更好的方式，记忆中有ChatAt方法可以实现
                    //让A随num的添加变B、C、D，处理的逻辑是将它转成一个byte加了再编码回来
                    byte[] bytes = "A".getBytes();
                    bytes[0] = (byte) (bytes[0] + num);
                    String A = new String(bytes,"ascii");
                    t.setText(A + ".");
                    temp = val;
                } else if (!temp.equals(val)) {
                    num = 0;
                    t.setText("A" + ".");
                    temp = val;
                }
                Element parent = numPr.getParent().getParent();
                List elements = parent.elements();

                elements.add(1, r);

            }
        }

    }

    //替换下划线为实下划线
    public static void underlineTo(Document document) {
        List list = document.selectNodes("//w:rPr/w:u");
        for (Object o : list) {
            Element u = (Element) o;
            Element r = u.getParent().getParent();

            List list1 = r.selectNodes("./w:t");
            for (Object o1 : list1) {
                Element t = (Element) o1;
                t.setText(t.getText().replace(" ", "_"));
            }
        }

    }
    //替换上标
    public static void superscript(Document document) {
        List list = document.selectNodes("//w:rPr/w:vertAlign");
        for (Object o : list) {
            Element u = (Element) o;
            Element r = u.getParent().getParent();

            List list1 = r.selectNodes("./w:t");
            for (Object o1 : list1) {
                Element t = (Element) o1;
                t.setText("&lt;sup&gt;"+t.getText()+"&lt;/sup&gt;");
            }
        }
    }
    private static Map<String, String> getMapPath(Document resXml) throws Exception {
        Map<String, String> idMap = new HashMap<>();
        Element root = resXml.getRootElement();
        for (Iterator it = root.elementIterator(); it.hasNext(); ) {
            Element element = (Element) it.next();
            String id = element.attributeValue("Id");
            String target = element.attributeValue("Target");
            idMap.put(id, target);
        }
//        用xpath匹配不到Relationship节点,Relationship是一个自闭合标签，但我匹配其他自闭合标签是正常的
//        List list = resXml.selectNodes("//Relationship");
//        for (Object o : list) {
//            Element node = (Element) o;
//            System.out.println(node.asXML());
//        }

        return idMap;
    }

    private static Map<String, String> getMapNumStart(Document numberingXml) {
//        获取num的id 获取abstract的id
//        最后两个map匹配
        Map<String, String> mapNum = new HashMap<>();
        Map<String, String> mapAbstractNum = new HashMap<>();
        Map<String, String> mapStart = new HashMap<>();
        List numList = numberingXml.selectNodes("//w:num");
        for (Object o : numList) {
            Element num = (Element) o;
            String numId = num.attributeValue("numId");
            String abstractNumId = null;
            List abstractNumList = num.selectNodes("./w:abstractNumId");
            for (Object o1 : abstractNumList) {
                Element abstractNum = (Element) o1;
                abstractNumId = abstractNum.attributeValue("val");
            }
            mapNum.put(numId, abstractNumId);
        }

        List absnumList = numberingXml.selectNodes("//w:abstractNum");
        for (Object o : absnumList) {
            Element absnum = (Element) o;
            List numFmtList = absnum.selectNodes("./w:lvl/w:numFmt");
            for (Object o1 : numFmtList) {
                Element numFmt = (Element) o1;
                if (numFmt.attributeValue("val").equals("decimal")){
                    String abstractNumId = absnum.attributeValue("abstractNumId");
                    String startNum = null;
                    List startList = absnum.selectNodes("./w:lvl/w:start");
                    for (Object o2 : startList) {
                        Element start = (Element) o2;
                        startNum = start.attributeValue("val");
                    }
                    mapAbstractNum.put(abstractNumId, startNum);
                }
            }

        }

        for (String id : mapNum.keySet()) {
            mapStart.put(id, mapAbstractNum.get(mapNum.get(id)));
        }
        return mapStart;
    }

    private static Map<String, String> getMapUpperStart(Document numberingXml) {
        Map<String, String> mapNum = new HashMap<>();
        Map<String, String> mapAbstractNum = new HashMap<>();
        Map<String, String> mapStart = new HashMap<>();


        List numList = numberingXml.selectNodes("//w:num");
        for (Object o : numList) {
            Element num = (Element) o;
            String numId = num.attributeValue("numId");
            String abstractNumId = null;
            List abstractNumList = num.selectNodes("./w:abstractNumId");
            for (Object o1 : abstractNumList) {
                Element abstractNum = (Element) o1;
                abstractNumId = abstractNum.attributeValue("val");
            }
            mapNum.put(numId, abstractNumId);
        }

        List absnumList = numberingXml.selectNodes("//w:abstractNum");
        for (Object o : absnumList) {
            Element absnum = (Element) o;
            List numFmtList = absnum.selectNodes("./w:lvl/w:numFmt");
            for (Object o1 : numFmtList) {
                Element numFmt = (Element) o1;
                if (numFmt.attributeValue("val").equals("upperLetter")){
                    String abstractNumId = absnum.attributeValue("abstractNumId");
                    String startNum = null;
                    List startList = absnum.selectNodes("./w:lvl/w:start");
                    for (Object o2 : startList) {
                        Element start = (Element) o2;
                        startNum = start.attributeValue("val");
                    }
                    mapAbstractNum.put(abstractNumId, startNum);
                }
            }

        }

        for (String id : mapNum.keySet()) {
            mapStart.put(id, mapAbstractNum.get(mapNum.get(id)));
        }
        return mapStart;
    }

    public static void textRight(Document document) {
        List list = document.selectNodes("//w:pPr/w:jc[@w:val=\"right\"]");
        for (Object o : list) {
            Node node = (Node) o;
            Element pPr = node.getParent();
            Element p = pPr.getParent();
            p.remove(pPr);
            List list1 = p.selectNodes("./w:r/w:t");
            String pText = "";
            for (int i = 0; i < list1.size(); i++) {
                Object o1 = list1.get(i);
                Node node1 = (Node) o1;
                pText = pText + node1.getText();
                node1.setText("");
                if (i == (list1.size()-1) ){
                    node1.setText("&lt;p align=\"right\"&gt;" + pText + "&lt;/p&gt;");
                }
            }
//            for (Object o1 : list1) {
//                Node node1 = (Node) o1;
//                node1.setText("&lt;p align=\"right\"&gt;" + node1.getText() + "&lt;/p&gt;");
//            }
        }
    }
}
